package com.javen.common;

import java.io.File;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.javen.common.hander.RenderingTimeHandler;
import com.javen.common.hander.SessionIdHandler;
import com.javen.common.hander.WebSocketHandler;
import com.javen.common.plugin.log.Slf4jLogFactory;
import com.javen.controller.FileController;
import com.javen.controller.IndexController;
import com.javen.controller.ShellController;
import com.javen.controller.UserController;
import com.javen.controller.WeixinApiController;
import com.javen.controller.WeixinMsgController;
import com.javen.controller.event.JfinalEventController;
import com.javen.controller.interceptor.SysLogInterceptor;
import com.javen.model._MappingKit;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.JFinal;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.c3p0.C3p0Plugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;
import com.jfinal.plugin.druid.IDruidStatViewAuth;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.render.ViewType;
import com.jfinal.template.Engine;
import com.jfinal.upload.OreillyCos;
import com.jfinal.weixin.sdk.api.ApiConfigKit;

import net.dreamlu.event.EventPlugin;

/**
 * @author Javen
 */
public class APPConfig extends JFinalConfig {
	static Log log = Log.getLog(APPConfig.class);
	private boolean isDev = false;

	/**
	 * 如果生产环境配置文件存在，则优先加载该配置，否则加载开发环境配置文件
	 *
	 * @param pro
	 *            生产环境配置文件
	 * @param dev
	 *            开发环境配置文件
	 */
	public void loadProp(String pro, String dev) {
		try {
			PropKit.use(pro);
		} catch (Exception e) {
			PropKit.use(dev);
		}
	}

	@Override
	public void afterJFinalStart() {
		log.info("afterJFinalStart");
		super.afterJFinalStart();
		// 设置文件上传重命名策略
		OreillyCos.setFileRenamePolicy(new UpFileRenamePolicy());
	}

	@Override
	public void beforeJFinalStop() {
		log.info("beforeJFinalStop");
		super.beforeJFinalStop();
	}

	/**
	 * 配置常量
	 */
	public void configConstant(Constants me) {
		// 加载少量必要配置，随后可用PropKit.get(...)获取值
		loadProp("javen_config_pro.txt", "javen_config.txt");
		isDev = PropKit.getBoolean("devMode", false);
		me.setDevMode(isDev);
		me.setEncoding("utf-8");
		// 设置Slf4日志
		me.setLogFactory(new Slf4jLogFactory());
		// 使用jsp
		me.setViewType(ViewType.JSP);
		me.setError404View("/WEB-INF/views/error/404.jsp");
		me.setError500View("/WEB-INF/views/error/500.jsp");
		// 设置上传文件保存的路径
		me.setBaseUploadPath(PathKit.getWebRootPath() + File.separator + "upload");
		// ApiConfigKit 设为开发模式可以在开发阶段输出请求交互的 xml 与 json 数据
		ApiConfigKit.setDevMode(me.getDevMode());

	}

	/**
	 * 配置路由
	 */
	public void configRoute(Routes me) {
		me.setBaseViewPath("/WEB-INF/views");
		// 微信
		me.add("/", IndexController.class);
		me.add("/msg", WeixinMsgController.class);
		me.add("/api", WeixinApiController.class);

		me.add("/file", FileController.class, "/");
		me.add("/user", UserController.class);
		me.add("/shell", ShellController.class);
		me.add("/event", JfinalEventController.class);

	}

	public static C3p0Plugin createC3p0Plugin() {
		return new C3p0Plugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim());
	}

	public static DruidPlugin createDruidPlugin() {
		String jdbcUrl = PropKit.get("jdbcUrl");
		String user = PropKit.get("user");
		String password = PropKit.get("password");
		log.error(jdbcUrl + " " + user + " " + password);
		// 配置druid数据连接池插件
		DruidPlugin dp = new DruidPlugin(jdbcUrl, user, password);
		// 配置druid监控
		dp.addFilter(new StatFilter());
		WallFilter wall = new WallFilter();
		wall.setDbType("mysql");
		dp.addFilter(wall);
		return dp;
	}

	/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {
		// 配置ActiveRecord插件
		DruidPlugin druidPlugin = createDruidPlugin();
		me.add(druidPlugin);
		C3p0Plugin c3p0Plugin = createC3p0Plugin();
		me.add(c3p0Plugin);

		ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
		arp.setShowSql(PropKit.getBoolean("devMode", false));
		me.add(arp);
		_MappingKit.mapping(arp);

		arp.setBaseSqlTemplatePath(PathKit.getRootClassPath() + "/sql");
		arp.addSqlTemplate("all_sqls.sql");

		// ehcahce插件配置
		me.add(new EhCachePlugin());

		// 初始化插件
		EventPlugin plugin = new EventPlugin();
		// 开启全局异步
		plugin.async();
		// // 设置扫描jar包，默认不扫描
		plugin.scanJar();
		// // 设置监听器默认包，默认全扫描
		plugin.scanPackage("com.javen.controller.event");
		me.add(plugin);
	}

	/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {
		me.addGlobalActionInterceptor(new SysLogInterceptor());
	}

	/**
	 * 配置处理器
	 */
	public void configHandler(Handlers me) {
		me.add(new ContextPathHandler("contextPath"));
		if (isDev) {
			me.add(new RenderingTimeHandler());
		}
		me.add(new SessionIdHandler());
		// me.add(new UserAgentHandler());
		// Druid监控
		DruidStatViewHandler dvh = new DruidStatViewHandler("/druid", new IDruidStatViewAuth() {

			@Override
			public boolean isPermitted(HttpServletRequest request) {
				return true;
			}
		});
		me.add(dvh);

		me.add(new WebSocketHandler("^/websocket"));
	}

	/**
	 * 建议使用 JFinal 手册推荐的方式启动项目 运行此 main
	 * 方法可以启动项目，此main方法可以放置在任意的Class类定义中，不一定要放于此
	 */
	public static void main(String[] args) {
		JFinal.start("src/main/webapp", 8080, "/", 5);// 启动配置项
	}

	@Override
	public void configEngine(Engine me) {

	}

}
